/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 combat_actor_model_definition.h

	$Header: /heroes4/combat_actor_model_definition.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( COMBAT_ACTOR_MODEL_DEFINITION_H_INCLUDED )
#define COMBAT_ACTOR_MODEL_DEFINITION_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <cassert>
#include <iosfwd>

#include "actor_model_definition.h"
#include "battlefield_metrics.h"
#include "combat_actor_action.h"
#include "resource_traits.h"

// ------------------------------------------------------------------------------
// t_combat_actor_model_definition_traits struct - used to pass information to
// the t_actor_model_definition class template
// ------------------------------------------------------------------------------

struct t_combat_actor_model_definition_traits
{
	// Types
	typedef t_combat_actor_action_id	t_action_id;

	// Static data
	enum { k_action_count = k_combat_actor_action_count };
	enum { k_cell_width = k_battlefield_cell_width };
	enum { k_cell_height = k_battlefield_cell_height };
	enum { k_max_footprint_size = 7 };
	enum { k_min_footprint_size = 0 };
};

// ------------------------------------------------------------------------------
// t_combat_actor_model_definition class
// ------------------------------------------------------------------------------

class t_combat_actor_model_definition
	:	public t_actor_model_definition< t_combat_actor_model_definition_traits >
{
public:
	// Static data
	enum { k_max_height = 255 };
	enum { k_min_height = 0 };

	// Constructor
	t_combat_actor_model_definition();

	// Member functions
	int						get_height() const;
	int						get_key_frame( t_combat_actor_action_id action ) const;
	t_map_point_3d const&	get_missile_origin( t_direction direction ) const;
	void					set_height( int new_height );
	void					set_key_frame( t_combat_actor_action_id action, int frame );
	void					set_missile_origin( t_direction direction, 
		                                        t_map_point_3d const& point );

private:
	// Data members
	int				m_height;
	int				m_key_frame[k_combat_actor_action_count];
	t_map_point_3d  m_missile_origin[k_direction_count];
};

// ------------------------------------------------------------------------------
// t_combat_actor_model_definition inline members
// ------------------------------------------------------------------------------

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
inline t_combat_actor_model_definition::t_combat_actor_model_definition()
	:	m_height( k_min_height )
{
	set_prewalk_length( 16 );
	set_walk_length( 64 );
	set_postwalk_length( 16 );
	memset( m_key_frame, 0, sizeof( m_key_frame ) );
}

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
inline int t_combat_actor_model_definition::get_height() const
{
	return m_height;
}

inline int t_combat_actor_model_definition::get_key_frame( t_combat_actor_action_id action ) const
{
	return m_key_frame[action];
}

inline t_map_point_3d const& 
t_combat_actor_model_definition::get_missile_origin( t_direction direction ) const
{
	return m_missile_origin[direction];
}

inline void t_combat_actor_model_definition::set_key_frame( t_combat_actor_action_id action, 
														    int frame )
{
	m_key_frame[action] = frame;
}

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
inline void t_combat_actor_model_definition::set_height( int new_height )
{
	assert( new_height >= k_min_height && new_height <= k_max_height );
	m_height = new_height;
}

inline void 
t_combat_actor_model_definition::set_missile_origin( t_direction direction, 
													 t_map_point_3d const& point )
{
	m_missile_origin[direction] = point;
}

// ------------------------------------------------------------------------------
// Helper free functions for t_combat_actor_model_definition
// ------------------------------------------------------------------------------

bool read( std::streambuf & stream, t_combat_actor_model_definition & definition );
bool write( std::streambuf & stream, t_combat_actor_model_definition const & definition );

// ------------------------------------------------------------------------------
// t_resource_traits< t_combat_actor_model_definition >
// ------------------------------------------------------------------------------

template <>
struct t_resource_traits< t_combat_actor_model_definition >
{
	static char const prefix[];
	static char const extension[];
};

#endif // !defined( COMBAT_ACTOR_MODEL_DEFINITION_H_INCLUDED )
